package com.suning.sawp.service.impl.promotion;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.domain.Sort.Order;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;

import com.google.common.base.Function;
import com.google.common.collect.Maps;
import com.suning.rsc.RscException;
import com.suning.sawp.constants.CacheKeyConstants;
import com.suning.sawp.constants.ConfigConstants;
import com.suning.sawp.constants.ErrorCodeConstants;
import com.suning.sawp.constants.LoggerConstants;
import com.suning.sawp.constants.PreChargeErrorConstants;
import com.suning.sawp.constants.PromotionConstants;
import com.suning.sawp.constants.PromotionErrorConstants;
import com.suning.sawp.dto.aircondition.CommInfoReq;
import com.suning.sawp.dto.aircondition.CouponReq;
import com.suning.sawp.dto.aircondition.ValidActivityIdReq;
import com.suning.sawp.dto.common.MyQueryParam;
import com.suning.sawp.dto.common.QueryResult;
import com.suning.sawp.dto.common.ReturnMsg;
import com.suning.sawp.dto.customer.CustshopFrequency;
import com.suning.sawp.dto.esb.CouponRuleQueryRtn;
import com.suning.sawp.dto.esb.LocateMemberInfo;
import com.suning.sawp.dto.esb.QryActDetailNewRsp;
import com.suning.sawp.dto.esb.QryActDetailNewRsp.ActDetail;
import com.suning.sawp.dto.esb.QryActDetailRsp;
import com.suning.sawp.dto.esb.QryActDetailRsp.ActivityDetail;
import com.suning.sawp.dto.esb.QryCouponListRsp;
import com.suning.sawp.dto.esb.QryCouponListRsp.CouponDetail;
import com.suning.sawp.dto.esb.QryCouponListRsp.CouponDetail.ProductDetail;
import com.suning.sawp.dto.esb.QryPromExecDetailReq;
import com.suning.sawp.dto.esb.QryPromExecDetailRsp;
import com.suning.sawp.dto.esb.QueryCouponRtn;
import com.suning.sawp.dto.esb.QueryPrechargeLimitRtn;
import com.suning.sawp.dto.esb.SendCouponRtn;
import com.suning.sawp.dto.mainpush.StoreManDto;
import com.suning.sawp.dto.precharge.CommonRtn;
import com.suning.sawp.dto.promotion.ActivityDetailInfo;
import com.suning.sawp.dto.promotion.CouponCommInfo;
import com.suning.sawp.dto.promotion.CouponRecordBean;
import com.suning.sawp.dto.promotion.CouponSendRecordBean;
import com.suning.sawp.dto.promotion.InnerCouponDetail;
import com.suning.sawp.dto.promotion.QueryActBean;
import com.suning.sawp.intf.dao.PromotionActivityDaoService;
import com.suning.sawp.intf.esb.MemberInfoService;
import com.suning.sawp.intf.esb.PosPreChargeService;
import com.suning.sawp.intf.esb.PromotionaMgmtService;
import com.suning.sawp.intf.esb.ShopFrequencyService;
import com.suning.sawp.intf.precharge.SequenceSerivce;
import com.suning.sawp.intf.promotion.InnerCouponService;
import com.suning.sawp.intf.promotion.PromotionActivityService;
import com.suning.sawp.intf.promotion.PromotionCouponService;
import com.suning.sawp.intf.store.StoreInfoService;
import com.suning.sawp.intf.storeman.StoreManService;
import com.suning.sawp.po.promotion.CouponRecord;
import com.suning.sawp.po.promotion.ValidActivity;
import com.suning.sawp.po.store.StoreInfo;
import com.suning.sawp.service.util.AESUtils;
import com.suning.sawp.service.util.ConfigUtil;
import com.suning.sawp.service.util.DJStringUtils;
import com.suning.sawp.service.util.DateUtils;
import com.suning.sawp.service.util.ExcelUtils;
import com.suning.sawp.service.util.RedisCacheUtils;
import com.suning.vgs.follow.remote.intf.StoreConsumerService;
import com.suning.vgs.follow.remote.intf.StoreManRemoteService;
import com.suning.vgs.follow.remote.store.ConsumerBehaviorDto;
import com.suning.vgs.follow.remote.store.ConsumerBehaviorType;

/**
 * 
 * 促销活动接口实现类<br>
 * 〈功能详细描述〉
 * 
 * @author Wuxiao
 * @see [相关类/方法]（可选）
 * @since [产品/模块版本] （可选）
 */
@Service
public class PromotionActivityServiceImpl implements PromotionActivityService {

    private static final Logger LOGGER = LoggerFactory.getLogger(LoggerConstants.SAWP_INTEGRATION);

    @Resource
    MongoTemplate mongoTemplate;

    @Resource
    PromotionCouponService promotionCouponService;

    @Autowired
    MemberInfoService memberInfoService;

    @Resource
    PromotionaMgmtService promotionaMgmtService;

    @Autowired
    StoreInfoService storeInfoService;

    @Autowired
    StoreManRemoteService storeManRemoteService;

    @Autowired
    StoreManService storeManService;

    @Autowired
    RedisCacheUtils cacheUtils;

    @Resource
    ShopFrequencyService shopFrequencyService;

    @Resource
    PromotionActivityDaoService promotionActivityDaoService;

    @Autowired
    StoreConsumerService storeConsumerService;

    @Resource
    PosPreChargeService posPreChargeService;

    @Autowired
    SequenceSerivce sequenceSerivce;
    
    @Resource
    InnerCouponService innerCouponService;
    
    
    private static final String COUPON_ORDER_ID_KEY = "SNSAWP_SEND_COUPON";

    private static final String SEND_COUPON_ORDER_PREFIX = "SNSAWP_";

    public static final String PARAM = "{param}";

    private final SimpleDateFormat sd = new SimpleDateFormat("yyyyMMdd");

    private final SimpleDateFormat sdTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    @Override
    public ReturnMsg<List<QueryActBean>> queryActivity(String type, String cityId, String oaAccountNo,
            Integer couponResource) {
        ReturnMsg<List<QueryActBean>> ret = new ReturnMsg<List<QueryActBean>>();
        // 校验入参合法性 type和工号不能为空且当type=0时,常用活动,cityId不能为空
        if (StringUtils.isBlank(type) || StringUtils.isBlank(oaAccountNo)) {
            ret.setRetFlag(ReturnMsg.FAIL);
            ret.setErrorCode(PromotionErrorConstants.ACT_QUERY_ERR_E001);
            ret.setErrorMessage(
                    PromotionErrorConstants.ACT_QUERY_ERR_MAP.get(PromotionErrorConstants.ACT_QUERY_ERR_E001));
            return ret;
        }
        List<QueryActBean> actList = new ArrayList<QueryActBean>();
        // 构造查询条件 查询店员已验证的促销活动
        Query query = new Query();
        Criteria criteria = new Criteria();
        criteria.and(ValidActivity.Attributes.OA_ACCOUNT_NO).is(oaAccountNo);
        criteria.and(ValidActivity.Attributes.END_TIME).gt(new Date());
        boolean onLineFlag = false;
        boolean offLineFlag = false;
        StoreManDto store = storeManService.queryStoreManAttachInfo(oaAccountNo);
        String storeCode = store != null ? store.getStoreCode() : "";
        // 线下券 来源集合
        Set<Integer> offlineSet = new HashSet<Integer>();
        offlineSet.add(PromotionConstants.PROMOT_COUPON_RESCOUCE_OFFLINE_STORE);
        offlineSet.add(PromotionConstants.PROMOT_COUPON_RESCOUCE_OFFLINE_MARKET);
        // 构造线上券活动查询条件
        Criteria criteriaOnline = new Criteria().and(ValidActivity.Attributes.COUPON_RESOURCE).nin(offlineSet);
        // 构造线下券活动查询条件
        Criteria criteriaOfflineStore = new Criteria().and(ValidActivity.Attributes.COUPON_RESOURCE)
                .is(PromotionConstants.PROMOT_COUPON_RESCOUCE_OFFLINE_STORE).and(ValidActivity.Attributes.STORE_CODE)
                .is(storeCode);
        // 构造线下券 超市 活动查询条件
        Criteria criteriaOfflineMarket = new Criteria().and(ValidActivity.Attributes.COUPON_RESOURCE)
                .is(PromotionConstants.PROMOT_COUPON_RESCOUCE_OFFLINE_MARKET).and(ValidActivity.Attributes.STORE_CODE)
                .is(storeCode);
        // 判断查询线上还是线下已验证活动
        if (couponResource == null || couponResource == PromotionConstants.PROMOT_COUPON_RESCOUCE_ONLINE) {
            onLineFlag = true;
            criteria.andOperator(criteriaOnline);
        } else if (couponResource == PromotionConstants.PROMOT_COUPON_RESCOUCE_OFFLINE) {
            offLineFlag = true;
            criteria.orOperator(criteriaOfflineStore, criteriaOfflineMarket);
        } else if (couponResource == PromotionConstants.PROMOT_COUPON_RESCOUCE_ALL) {
            onLineFlag = true;
            offLineFlag = true;
            criteria.orOperator(criteriaOnline, criteriaOfflineStore, criteriaOfflineMarket);
        }
        query.addCriteria(criteria);
        List<ValidActivity> list = mongoTemplate.find(query, ValidActivity.class);
        if (PromotionConstants.ACT_QUERY_TYPE_COMMON.equals(type)) {
            ret.setRetFlag(ReturnMsg.SUCCESS);
            SimpleDateFormat sdFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            if (CollectionUtils.isNotEmpty(list)) {
                for (ValidActivity validAct : list) {
                    QueryActBean act = new QueryActBean();
                    if (StringUtils.isNotBlank(validAct.getActivityId())) {
                        act.setActivityId(AESUtils.encrypt(validAct.getActivityId(), ConfigConstants.AES_KEY));
                    } else {
                        act.setActivityId("");
                    }
                    act.setActivityName(validAct.getActivityName());
                    // 对日期进行格式化
                    act.setStartTime(sdFormat.format(validAct.getStartTime()));
                    // 对日期进行格式化
                    act.setEndTime(sdFormat.format(validAct.getEndTime()));
                    act.setSecurityKey(validAct.getActivitySecretKey());
                    // 查询的数据都为已验证
                    act.setIsValide(QueryActBean.IsValid.IS_VALID_Y);
                    act.setCouponResource(validAct.getCouponResource() == null
                            ? Integer.valueOf(PromotionConstants.PROMOT_COUPON_RESCOUCE_ONLINE)
                            : validAct.getCouponResource());
                    act.setStoreCode(validAct.getStoreCode() == null ? "" : validAct.getStoreCode());
                    if (StringUtils.isNotBlank(validAct.getCityId())) {
                        act.setCityId(validAct.getCityId());
                    }
                    actList.add(act);
                }
            }
            ret.setData(actList);
        } else if (PromotionConstants.ACT_QUERY_TYPE_CITY.equals(type)) {
            // 全国活动，返回城市ID为空
            String cityIdParam = StringUtils.isBlank(cityId) ? "" : cityId;
            if (onLineFlag) {
                try {
                    // 查询线上促销活动
                    QryActDetailRsp respOnline = promotionCouponService.queryProActivityList(cityIdParam,
                            PromotionConstants.PROMOT_COUPON_RESCOUCE_ONLINE, null);
                    ret = createRtn(actList, ret, respOnline, cityIdParam, list,
                            PromotionConstants.PROMOT_COUPON_RESCOUCE_ONLINE, "");
                } catch (Exception e) {
                    LOGGER.error(String.format("店+发券 查询线上券异常,cityId=%s", cityIdParam), e);
                }
            }
            if (offLineFlag) {
                try {
                    if (StringUtils.isNotBlank(storeCode)) {
                        // 查询线下促销活动 门店
                        QryActDetailRsp respOffline = promotionCouponService.queryProActivityList(cityIdParam,
                                PromotionConstants.PROMOT_COUPON_RESCOUCE_OFFLINE_STORE, store.getStoreCode());
                        ret = createRtn(actList, ret, respOffline, cityIdParam, list,
                                PromotionConstants.PROMOT_COUPON_RESCOUCE_OFFLINE_STORE, storeCode);
                        // 查询线下促销活动 超市 临时方案
                        QryActDetailRsp respOfflineMarket = promotionCouponService.queryProActivityList(cityIdParam,
                                PromotionConstants.PROMOT_COUPON_RESCOUCE_OFFLINE_MARKET, store.getStoreCode());
                        ret = createRtn(actList, ret, respOfflineMarket, cityIdParam, list,
                                PromotionConstants.PROMOT_COUPON_RESCOUCE_OFFLINE_MARKET, storeCode);
                    }
                } catch (Exception e) {
                    LOGGER.error(String.format("店+发券 查询线下券异常,storeCode=%s，cityId=%s", storeCode, cityIdParam), e);
                }
            }
        }
        return ret;
    }

    
    @Override
    public ReturnMsg<List<QueryActBean>> queryActivityListNew(String type, String cityId, String oaAccountNo,
            Integer couponResource) {

        ReturnMsg<List<QueryActBean>> ret = new ReturnMsg<List<QueryActBean>>();
        // 校验入参合法性 type和工号不能为空且当type=0时,常用活动,cityId不能为空
        if (StringUtils.isBlank(type) || StringUtils.isBlank(oaAccountNo)) {
            ret.setRetFlag(ReturnMsg.FAIL);
            ret.setErrorCode(PromotionErrorConstants.ACT_QUERY_ERR_E001);
            ret.setErrorMessage(
                    PromotionErrorConstants.ACT_QUERY_ERR_MAP.get(PromotionErrorConstants.ACT_QUERY_ERR_E001));
            return ret;
        }
        List<QueryActBean> actList = new ArrayList<QueryActBean>();
        // 构造查询条件 查询店员已验证的促销活动
        Query query = new Query();
        Criteria criteria = new Criteria();
        criteria.and(ValidActivity.Attributes.OA_ACCOUNT_NO).is(oaAccountNo);
        criteria.and(ValidActivity.Attributes.END_TIME).gt(new Date());
        boolean onLineFlag = false;
        boolean offLineFlag = false;
        StoreManDto store = storeManService.queryStoreManAttachInfo(oaAccountNo);
        String storeCode = store != null ? store.getStoreCode() : "";
        // 线下券 来源集合
        Set<Integer> offlineSet = new HashSet<Integer>();
        offlineSet.add(PromotionConstants.PROMOT_COUPON_RESCOUCE_OFFLINE_STORE);
        offlineSet.add(PromotionConstants.PROMOT_COUPON_RESCOUCE_OFFLINE_MARKET);
        // 构造线上券活动查询条件
        Criteria criteriaOnline = new Criteria().and(ValidActivity.Attributes.COUPON_RESOURCE).nin(offlineSet);
        // 构造线下券活动查询条件
        Criteria criteriaOfflineStore = new Criteria().and(ValidActivity.Attributes.COUPON_RESOURCE)
                .is(PromotionConstants.PROMOT_COUPON_RESCOUCE_OFFLINE_STORE).and(ValidActivity.Attributes.STORE_CODE)
                .is(storeCode);
        // 构造线下券 超市 活动查询条件
        Criteria criteriaOfflineMarket = new Criteria().and(ValidActivity.Attributes.COUPON_RESOURCE)
                .is(PromotionConstants.PROMOT_COUPON_RESCOUCE_OFFLINE_MARKET).and(ValidActivity.Attributes.STORE_CODE)
                .is(storeCode);
        // 判断查询线上还是线下已验证活动
        if (couponResource == null || couponResource == PromotionConstants.PROMOT_COUPON_RESCOUCE_ONLINE) {
            onLineFlag = true;
            criteria.andOperator(criteriaOnline);
        } else if (couponResource == PromotionConstants.PROMOT_COUPON_RESCOUCE_OFFLINE) {
            offLineFlag = true;
            criteria.orOperator(criteriaOfflineStore, criteriaOfflineMarket);
        } else if (couponResource == PromotionConstants.PROMOT_COUPON_RESCOUCE_ALL) {
            onLineFlag = true;
            offLineFlag = true;
            criteria.orOperator(criteriaOnline, criteriaOfflineStore, criteriaOfflineMarket);
        }
        query.addCriteria(criteria);
        List<ValidActivity> list = mongoTemplate.find(query, ValidActivity.class);
        if (PromotionConstants.ACT_QUERY_TYPE_COMMON.equals(type)) {
            ret.setRetFlag(ReturnMsg.SUCCESS);
            SimpleDateFormat sdFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            if (CollectionUtils.isNotEmpty(list)) {
                for (ValidActivity validAct : list) {
                    QueryActBean act = new QueryActBean();
                    if (StringUtils.isNotBlank(validAct.getActivityId())) {
                        act.setActivityId(AESUtils.encrypt(validAct.getActivityId(), ConfigConstants.AES_KEY));
                    } else {
                        LOGGER.error("validAct is error for ActivityId is blank , validAct :" + validAct);
                        continue;
                    }
                    act.setActivityName(validAct.getActivityName());
                    // 对日期进行格式化
                    act.setStartTime(sdFormat.format(validAct.getStartTime()));
                    // 对日期进行格式化
                    act.setEndTime(sdFormat.format(validAct.getEndTime()));
                    act.setSecurityKey(validAct.getActivitySecretKey());
                    // 查询的数据都为已验证
                    act.setIsValide(QueryActBean.IsValid.IS_VALID_Y);
                    act.setCouponResource(validAct.getCouponResource() == null
                            ? Integer.valueOf(PromotionConstants.PROMOT_COUPON_RESCOUCE_ONLINE)
                            : validAct.getCouponResource());
                    act.setStoreCode(validAct.getStoreCode() == null ? "" : validAct.getStoreCode());
                    //为老版本常用活动确实券规则编码数据补足数据
                   String  couponRuleCode  = validAct.getCouponRuleCode();
                    if(StringUtils.isBlank(couponRuleCode)){
                        // 全国活动，返回城市ID为空
                        String cityIdParam = StringUtils.isBlank(cityId) ? "" : cityId;
                        couponRuleCode = updateCouponRuleCode(validAct,onLineFlag,offLineFlag,store.getStoreCode(),cityIdParam);
                    }
                    act.setCouponRuleCode(couponRuleCode);
                    act.setCouponType(validAct.getCouponType());
                    act.setCouponValue(validAct.getCouponValue());
                    if (StringUtils.isNotBlank(validAct.getCityId())) {
                        act.setCityId(validAct.getCityId());
                    }
                    //如果查询不出来券规则编码
                    if(StringUtils.isNotBlank(couponRuleCode)){
                        actList.add(act);
                    }
                }
            }
            ret.setData(actList);
        } else if (PromotionConstants.ACT_QUERY_TYPE_CITY.equals(type)) {
            // 全国活动，返回城市ID为空
            String cityIdParam = StringUtils.isBlank(cityId) ? "" : cityId;
            if (onLineFlag) {
                try {
                    // 查询线上促销活动
                    QryActDetailNewRsp respOnline = promotionCouponService.queryProActivityListNew(cityIdParam,
                            PromotionConstants.PROMOT_COUPON_RESCOUCE_ONLINE, storeCode);
                    ret = createRtnNew(actList, ret, respOnline, cityIdParam, list,
                            PromotionConstants.PROMOT_COUPON_RESCOUCE_ONLINE,storeCode);
                } catch (Exception e) {
                    LOGGER.error(String.format("店+发券 查询线上券异常,cityId=%s", cityIdParam), e);
                }
            }
            if (offLineFlag) {
                try {
                    if (StringUtils.isNotBlank(storeCode)) {
                        // 查询线下促销活动 门店
                        QryActDetailNewRsp respOffline = promotionCouponService.queryProActivityListNew(cityIdParam,
                                PromotionConstants.PROMOT_COUPON_RESCOUCE_OFFLINE_STORE, store.getStoreCode());
                        ret = createRtnNew(actList, ret, respOffline, cityIdParam, list,
                                PromotionConstants.PROMOT_COUPON_RESCOUCE_OFFLINE_STORE, storeCode);
                        // 查询线下促销活动 超市 临时方案
                        QryActDetailNewRsp respOfflineMarket = promotionCouponService.queryProActivityListNew(cityIdParam,
                                PromotionConstants.PROMOT_COUPON_RESCOUCE_OFFLINE_MARKET, store.getStoreCode());
                        ret = createRtnNew(actList, ret, respOfflineMarket, cityIdParam, list,
                                PromotionConstants.PROMOT_COUPON_RESCOUCE_OFFLINE_MARKET, storeCode);
                    }
                } catch (Exception e) {
                    LOGGER.error(String.format("店+发券 查询线下券异常,storeCode=%s，cityId=%s", storeCode, cityIdParam), e);
                }
            }
        }
        return ret;
    
    }
    
    private ReturnMsg<List<QueryActBean>> createRtnNew(List<QueryActBean> actList, ReturnMsg<List<QueryActBean>> ret,
            QryActDetailNewRsp resp, String cityId, List<ValidActivity> list,
            int couponResource, String storeCode) {
        if (resp != null) {
            if (PromotionConstants.SUCCESS.equals(resp.getRequestResult()) && resp.getActInfoList() != null) {
                for (ActDetail act : resp.getActInfoList()) {
                    QueryActBean bean = new QueryActBean();
                    bean.setActivityId(StringUtils.isNotBlank(act.getActivityId())
                            ? AESUtils.encrypt(act.getActivityId(), ConfigConstants.AES_KEY) : "");
                    bean.setActivityName(act.getActivityName());
                    if(StringUtils.isNotBlank(act.getVerifyStartTime()) && StringUtils.isNotBlank(act.getVerifyEndTime())){
                        bean.setStartTime(DateUtils.getDateStrByFormat(DateUtils.getDateByStr(act.getVerifyStartTime(), DateUtils.ACCURATE_MINUTES_PATTERN_2), DateUtils.DEFAULT_TIME_PATTERN));
                        bean.setEndTime(DateUtils.getDateStrByFormat(DateUtils.getDateByStr(act.getVerifyEndTime(), DateUtils.ACCURATE_MINUTES_PATTERN_2), DateUtils.DEFAULT_TIME_PATTERN));
                    }
                    bean.setSecurityKey(act.getActivitySecretKey());
                    bean.setCityId(cityId);
                    bean.setIsValide(QueryActBean.IsValid.IS_VALID_N);
                    bean.setCouponRuleCode(StringUtils.isNotBlank(act.getCouponRuleId())
                            ? AESUtils.encrypt(act.getCouponRuleId(), ConfigConstants.AES_KEY) : "");
                    // 判断接口返回的活动列表是否存在已验证的活动
                    for (ValidActivity validAct : list) {
                        if (act.getActivityId().equals(validAct.getActivityId())) {
                            bean.setIsValide(QueryActBean.IsValid.IS_VALID_Y);
                            break;
                        }
                    }
                    bean.setCouponResource(couponResource);
                    bean.setStoreCode(storeCode);
                    bean.setCouponType(act.getCouponType());
                    bean.setCouponValue(act.getCouponValue());
                    actList.add(bean);
                }
                ret.setData(actList);
            } else {
                ret.setErrorCode(resp.getErrorCode());
                ret.setErrorMessage(resp.getFailedReson());
            }
        } else if (ret.getData() == null) {
            ret.setRetFlag(ReturnMsg.FAIL);
            ret.setErrorCode(ErrorCodeConstants.ERR_0002);
            ret.setErrorCode(ErrorCodeConstants.ERR_MAP.get(ErrorCodeConstants.ERR_0002));
        }
        return ret;
    
    }

    /**
     * 
     *
     * @param validAct
     * @param onLineFlag
     * @param offLineFlag
     * @param storeCode
     * @param cityIdParam
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    private String updateCouponRuleCode(ValidActivity validAct, boolean onLineFlag, boolean offLineFlag, String storeCode, String cityIdParam) {
        
        //查询该用户对应的券列表
        List<ActDetail> resultList = new ArrayList<ActDetail>();
        if (onLineFlag) {
            try {
                // 查询线上促销活动
                QryActDetailNewRsp respOnline = promotionCouponService.queryProActivityListNew(cityIdParam,
                        PromotionConstants.PROMOT_COUPON_RESCOUCE_ONLINE, storeCode);
                if (PromotionConstants.SUCCESS.equals(respOnline.getRequestResult()) && respOnline.getActInfoList() != null) {
                    resultList.addAll(respOnline.getActInfoList());
                }
            } catch (Exception e) {
                LOGGER.error(String.format("updateCouponRuleCode 店+发券 查询线上券异常,cityId=%s", cityIdParam), e);
            }
        }
        if (offLineFlag) {
            try {
                if (StringUtils.isNotBlank(storeCode)) {
                    // 查询线下促销活动 门店
                    QryActDetailNewRsp respOffline = promotionCouponService.queryProActivityListNew(cityIdParam,
                            PromotionConstants.PROMOT_COUPON_RESCOUCE_OFFLINE_STORE, storeCode);
                    if (PromotionConstants.SUCCESS.equals(respOffline.getRequestResult()) && respOffline.getActInfoList() != null) {
                        resultList.addAll(respOffline.getActInfoList());
                    }
                    // 查询线下促销活动 超市 临时方案
                    QryActDetailNewRsp respOfflineMarket = promotionCouponService.queryProActivityListNew(cityIdParam,
                            PromotionConstants.PROMOT_COUPON_RESCOUCE_OFFLINE_MARKET, storeCode);
                    if (PromotionConstants.SUCCESS.equals(respOfflineMarket.getRequestResult()) && respOfflineMarket.getActInfoList() != null) {
                        resultList.addAll(respOfflineMarket.getActInfoList());
                    }
                }
            } catch (Exception e) {
                LOGGER.error(String.format(" updateCouponRuleCode 店+发券 查询线下券异常,storeCode=%s，cityId=%s", storeCode, cityIdParam), e);
            }
        }
        //遍历券列表查询对应的缺失数据对该数据进行补数
        String couponRuleCode = "";
        for(ActDetail detail : resultList){
            if(detail != null && validAct.getActivityId().equals(detail.getActivityId())){
                couponRuleCode = detail.getCouponRuleId();
                break;
            }
        }
        
        if(StringUtils.isNotBlank(couponRuleCode)){
            LOGGER.info("updateCouponRuleCode for couponRuleCode  :" + couponRuleCode);
            couponRuleCode = StringUtils.isNotBlank(couponRuleCode)
            ? AESUtils.encrypt(couponRuleCode, ConfigConstants.AES_KEY) : "";
            Query query = new Query();
            Criteria criteriaHoriz = new Criteria();
            criteriaHoriz.and(ValidActivity.Attributes.ID).is(validAct.getId());
            query.addCriteria(criteriaHoriz);
            Update update = new Update();
            update.set(ValidActivity.Attributes.COUPON_RULE_CODE, couponRuleCode);
            mongoTemplate.updateFirst(query, update, ValidActivity.class);
        }
        
        return couponRuleCode;
    }

    
    private ReturnMsg<List<QueryActBean>> createRtn(List<QueryActBean> actList, ReturnMsg<List<QueryActBean>> ret,
            QryActDetailRsp resp, String cityId, List<ValidActivity> list, Integer couponResource, String storeCode) {
        if (resp != null) {
            if (PromotionConstants.SUCCESS.equals(resp.getRequestResult()) && resp.getActivityList() != null) {
                for (ActivityDetail act : resp.getActivityList()) {
                    QueryActBean bean = new QueryActBean();
                    bean.setActivityId(StringUtils.isNotBlank(act.getActivityId())
                            ? AESUtils.encrypt(act.getActivityId(), ConfigConstants.AES_KEY) : "");
                    bean.setActivityName(act.getActivityName());
                    bean.setStartTime(act.getStartTime());
                    bean.setEndTime(act.getEndTime());
                    bean.setSecurityKey(act.getActivitySecretKey());
                    bean.setCityId(cityId);
                    bean.setIsValide(QueryActBean.IsValid.IS_VALID_N);
                    // 判断接口返回的活动列表是否存在已验证的活动
                    for (ValidActivity validAct : list) {
                        if (act.getActivityId().equals(validAct.getActivityId())) {
                            bean.setIsValide(QueryActBean.IsValid.IS_VALID_Y);
                            break;
                        }
                    }
                    bean.setCouponResource(couponResource);
                    bean.setStoreCode(storeCode);
                    actList.add(bean);
                }
                ret.setData(actList);
            } else {
                ret.setErrorCode(resp.getErrorCode());
                ret.setErrorMessage(resp.getFailedReson());
            }
        } else if (ret.getData() == null) {
            ret.setRetFlag(ReturnMsg.FAIL);
            ret.setErrorCode(ErrorCodeConstants.ERR_0002);
            ret.setErrorCode(ErrorCodeConstants.ERR_MAP.get(ErrorCodeConstants.ERR_0002));
        }
        return ret;
    }

    @Override
    public QueryResult<CouponRecordBean> queryCouponRecord(MyQueryParam<String> param) {

        Integer currIndex = param.getCurrIndex();
        Integer pageSize = param.getPageSize();
        // 获取最大分页查询数量 如果超过最大默认值，取默认值
        Integer queryLimit = Integer.valueOf(ConfigUtil.getConfig(ConfigConstants.SAWP_CONFIG_PATH,
                ConfigConstants.COUPON_RECORD_QUERY_LIMIT, ConfigConstants.DEFAULT_QUERY_COUPON_LIMIT));
        pageSize = pageSize > queryLimit ? queryLimit : pageSize;
        // 初始化db查询参数
        Query query = new Query();
        Criteria criteria = new Criteria();
        criteria.and(CouponRecord.Attributes.OA_ACCOUNT_NO).is(param.getQueryParam());
        query.addCriteria(criteria);
        int totalSize = (int) mongoTemplate.count(query, CouponRecord.class);
        // 分页参数
        query.skip(currIndex);
        query.limit(pageSize);
        // 排序参数 按照发送时间倒序
        query.with(new Sort(new Order(Direction.DESC, CouponRecord.Attributes.SEND_TIME)));
        List<CouponRecord> list = mongoTemplate.find(query, CouponRecord.class);
        List<CouponRecordBean> queryList = new ArrayList<CouponRecordBean>();
        List<String> custList = new ArrayList<String>();
        if (CollectionUtils.isNotEmpty(list)) {
            SimpleDateFormat sdFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            for (CouponRecord coupon : list) {
                CouponRecordBean queryBean = new CouponRecordBean();
                custList.add(coupon.getCustNo());
                queryBean.setActivityId(coupon.getActivityId());
                queryBean.setActivityName(coupon.getActivityName());
                queryBean.setStartTime(sdFormat.format(coupon.getActStartTime()));
                queryBean.setEndTime(sdFormat.format(coupon.getActEndTime()));
                // 手机号加密处理 店+3.3.2需求 客户端需要打电话
                queryBean.setMobile(AESUtils.encrypt(coupon.getTelNo(), ConfigConstants.AES_KEY));
                queryBean.setEncryMobile(DJStringUtils.sensitiveHandleEx(coupon.getTelNo(), 3, 2));
                queryBean.setCustNo(coupon.getCustNo());
                queryBean.setPerformTime(sdFormat.format(coupon.getSendTime()));
                // 从zookeeper上取会员头像url
                // 会员画像url
                String memberProtraitUrl = DJStringUtils.getMemberProtraitUrl(coupon.getCustNo());
                queryBean.setPortraitUrl(memberProtraitUrl);
                queryList.add(queryBean);
            }
            // 批量更新首复购标记
            batchUpdateDealType(queryList, custList);
        }

        // 初始化返回对象
        QueryResult<CouponRecordBean> result = new QueryResult<CouponRecordBean>();
        result.setTotalSize(totalSize);
        // 设置当前页数据列表
        result.setRecords(queryList);
        return result;
    }

    /**
     * 批量更新首复购标记
     * 
     * @param queryList
     * @param custList
     */
    private void batchUpdateDealType(List<CouponRecordBean> queryList, List<String> custList) {
        Map<String, String> frequencyList = shopFrequencyService.queryShopFrequency(custList);
        for (CouponRecordBean record : queryList) {
            String frequency = frequencyList.get(record.getCustNo());
            CustshopFrequency custshopFrequency = DJStringUtils.getDealType(frequency);
            record.setDealTypeTxt(custshopFrequency.getDealTypeTxt());
            record.setDealType(custshopFrequency.getDealType());
            record.setCustNo(AESUtils.encrypt(record.getCustNo(), ConfigConstants.AES_KEY));
        }
    }

    @Override
    public ReturnMsg<ActivityDetailInfo> queryActivityDetail(String activityIdEncrypt, String mobile, String staffId) {
        ReturnMsg<ActivityDetailInfo> ret = new ReturnMsg<ActivityDetailInfo>();
        ActivityDetailInfo activityDetail = new ActivityDetailInfo();
        String activityId = AESUtils.decrypt(activityIdEncrypt, ConfigConstants.AES_KEY);
        // 查询已校验的活动信息
        ValidActivity activity = queryActByActId(staffId, activityId);
        if (activity == null) {
            ret.setError(PromotionErrorConstants.COUPON_SEND_ERR_E003, PromotionErrorConstants.COUPON_SEND_ERR_MAP);
            return ret;
        }
        LocateMemberInfo memberInfo = memberInfoService.locateMemberByMobileNo(mobile);
        if (null != memberInfo && StringUtils.isNotBlank(memberInfo.getCustNum())) {
            // 查询券详情
            String branchCode = activity.getBranchCode();
            if (StringUtils.isBlank(branchCode)) {
                // 分公司编码补偿逻辑前置，因为有些门店信息MQ变更通知会比较滞后
                StoreInfo store = storeInfoService.queryStoreByCode(activity.getStoreCode());
                branchCode = store != null ? store.getSaleBranchCode() : "";
                updateValidActivityBranchCode(branchCode, activityId, activity.getOaAccountNo());
                activity.setBranchCode(branchCode);
            }
            QueryCouponRtn couponRtn = promotionCouponService.queryCouponDetail(activityId, memberInfo.getCustNum(),
                    activity.getActivitySecretKey(), activity.getCityId(), activity);
            if (null != couponRtn) {
                String couponId = couponRtn.getCouponId();
                activityDetail.setCouponId(StringUtils.isNotBlank(couponId) ? couponRtn.getCouponId() : "");
                activityDetail.setCouponTypeTxt(
                        StringUtils.isNotBlank(couponRtn.getCouponType()) ? couponRtn.getCouponType() : "");
                activityDetail.setCouponValue(
                        StringUtils.isNotBlank(couponRtn.getCouponAmount()) ? couponRtn.getCouponAmount() : "");
                // 查询券规则
                CouponRuleQueryRtn couponRule = promotionCouponService.queryCouponRuleDetail(couponId);
                if (null != couponRule) {
                    // 查询券规则详情接口返回券规则名称作为券名称 产品确认 ---wuxiao
                    activityDetail.setCouponName(couponRule.getCouponRulesName());
                    // 用券规则 全额抵用
                    activityDetail.setCouponRule(couponRule.getRewardsPreferential());
                    activityDetail.setUseGuide(couponRule.getCouponRulesShowMsg());
                    List<String> storeNameList = couponRule.getStoreNameList();
                    // 增加用券范围字段拼接,拼接规则按照产品提供 限..终端类型名称...,...商品类别....不可用
                    // ---wuxiao
                    List<String> noUseList = couponRule.getNoUseList();
                    List<String> terminalList = couponRule.getTerminalList();
                    String terminalRule = "";
                    if (CollectionUtils.isNotEmpty(terminalList)) {
                        StringBuilder sb = new StringBuilder();
                        for (String s : terminalList) {
                            sb.append(s).append("、");
                        }
                        String template = ConfigUtil.getConfig(ConfigConstants.SAWP_CONFIG_PATH,
                                ConfigConstants.TERMINAL_TEMPLATE, ConfigConstants.DEFAULT_TERMINAL_TEMPLATE);
                        terminalRule = template.replace(PARAM, sb.toString().substring(0, sb.toString().length() - 1));
                    }
                    String noUseRule = "";
                    if (CollectionUtils.isNotEmpty(noUseList)) {
                        StringBuilder sb = new StringBuilder();
                        for (String s : noUseList) {
                            sb.append(s).append("、");
                        }
                        String template = ConfigUtil.getConfig(ConfigConstants.SAWP_CONFIG_PATH,
                                ConfigConstants.NO_USE_TEMPLATE, ConfigConstants.DEFAULT_NO_USE_TEMPLATE);
                        noUseRule = template.replace(PARAM, sb.toString().substring(0, sb.toString().length() - 1));
                    }
                    if (StringUtils.isNotBlank(terminalRule) && StringUtils.isNotBlank(noUseRule)) {
                        activityDetail.setProductsTxt(terminalRule + "，" + noUseRule);
                    } else {
                        activityDetail.setProductsTxt(terminalRule + noUseRule);
                    }
                    if (CollectionUtils.isNotEmpty(storeNameList)) {
                        StringBuilder sb = new StringBuilder();
                        for (String storeName : storeNameList) {
                            sb.append(storeName).append(",");
                        }
                        // 可用店铺列表文本，逗号分隔，最后一个逗号截取掉
                        String storesTxt = sb.toString().substring(0, sb.toString().length() - 1);
                        activityDetail.setStoresTxt(storesTxt);
                    }
                }
            }

            // 券当天可发剩余 和 总的可发剩余
            QryPromExecDetailReq req = new QryPromExecDetailReq();
            req.setActivityId(activityId);
            try {
                QryPromExecDetailRsp rsp = promotionaMgmtService.queryPromotionExecDetail(req);
                if (null != rsp) {
                    activityDetail.setLeftTotal(StringUtils.isNotBlank(rsp.getActRemainCount())
                            ? Integer.parseInt(rsp.getActRemainCount()) : 0);
                    activityDetail.setTodayLeft(StringUtils.isNotBlank(rsp.getDayActRemainCount())
                            ? Integer.parseInt(rsp.getDayActRemainCount()) : 0);
                }
            } catch (RscException e) {
                LOGGER.error("查询券剩余量失败,activityId=" + activityId + ",error=" + e);
            }
            // 线下券查询剩余额度
            if (isOffLineCoupon(activity.getCouponResource())) {
                QueryPrechargeLimitRtn queryRtn = posPreChargeService.posQueryPrechargeLimit(activity.getStoreCode(),
                        activity.getBranchCode());
                if (queryRtn != null && PreChargeErrorConstants.QUREY_REMIAN_SUCCESS.equals(queryRtn.getErrFlag())) {
                    activityDetail.setCouponLimit(queryRtn.getCouponLimit());
                }
            }
            activityDetail.setActivityId(AESUtils.encrypt(activityId, ConfigConstants.AES_KEY));
            activityDetail.setActivityName(activity.getActivityName());
            activityDetail.setStartTime(sdTime.format(activity.getStartTime()));
            activityDetail.setEndTime(sdTime.format(activity.getEndTime()));

            ret.setData(activityDetail);
            ret.setRetFlag(ReturnMsg.SUCCESS);
        } // 会员编码为空
        else {
            ret.setRetFlag(ReturnMsg.FAIL);
            ret.setErrorCode("E001");
            ret.setErrorMessage("会员编码为空，查询活动详情失败");
        }
        return ret;
    }

    @Override
    public ReturnMsg<ActivityDetailInfo> queryActivityDetailNew(String couponRuleCodeEncrypt, String staffId,String activityIdEncrypt) {

        ReturnMsg<ActivityDetailInfo> ret = new ReturnMsg<ActivityDetailInfo>();
        ActivityDetailInfo activityDetail = new ActivityDetailInfo();
        String activityId = AESUtils.decrypt(activityIdEncrypt, ConfigConstants.AES_KEY);
        String couponRuleCode = AESUtils.decrypt(couponRuleCodeEncrypt, ConfigConstants.AES_KEY);
        // 查询已校验的活动信息
        ValidActivity activity = queryActByActId(staffId, activityId);
        if (activity == null) {
            ret.setError(PromotionErrorConstants.COUPON_SEND_ERR_E003, PromotionErrorConstants.COUPON_SEND_ERR_MAP);
            return ret;
        }

        // 查询券规则
        CouponRuleQueryRtn couponRule = promotionCouponService.queryCouponRuleDetail(couponRuleCode);
        if (null != couponRule) {
            activityDetail.setCouponId(couponRuleCode);
            activityDetail.setCouponTypeTxt(activity.getCouponType());
            activityDetail.setCouponValue(activity.getCouponValue());
            // 查询券规则详情接口返回券规则名称作为券名称 产品确认 ---wuxiao
            activityDetail.setCouponName(couponRule.getCouponRulesName());
            // 用券规则 全额抵用
            activityDetail.setCouponRule(couponRule.getRewardsPreferential());
            activityDetail.setUseGuide(couponRule.getCouponRulesShowMsg());
            List<String> storeNameList = couponRule.getStoreNameList();
            // 增加用券范围字段拼接,拼接规则按照产品提供 限..终端类型名称...,...商品类别....不可用
            // ---wuxiao
            List<String> noUseList = couponRule.getNoUseList();
            List<String> terminalList = couponRule.getTerminalList();
            String terminalRule = "";
            if (CollectionUtils.isNotEmpty(terminalList)) {
                StringBuilder sb = new StringBuilder();
                for (String s : terminalList) {
                    sb.append(s).append("、");
                }
                String template = ConfigUtil.getConfig(ConfigConstants.SAWP_CONFIG_PATH,
                        ConfigConstants.TERMINAL_TEMPLATE, ConfigConstants.DEFAULT_TERMINAL_TEMPLATE);
                terminalRule = template.replace(PARAM, sb.toString().substring(0, sb.toString().length() - 1));
            }
            String noUseRule = "";
            if (CollectionUtils.isNotEmpty(noUseList)) {
                StringBuilder sb = new StringBuilder();
                for (String s : noUseList) {
                    sb.append(s).append("、");
                }
                String template = ConfigUtil.getConfig(ConfigConstants.SAWP_CONFIG_PATH,
                        ConfigConstants.NO_USE_TEMPLATE, ConfigConstants.DEFAULT_NO_USE_TEMPLATE);
                noUseRule = template.replace(PARAM, sb.toString().substring(0, sb.toString().length() - 1));
            }
            if (StringUtils.isNotBlank(terminalRule) && StringUtils.isNotBlank(noUseRule)) {
                activityDetail.setProductsTxt(terminalRule + "，" + noUseRule);
            } else {
                activityDetail.setProductsTxt(terminalRule + noUseRule);
            }
            if (CollectionUtils.isNotEmpty(storeNameList)) {
                StringBuilder sb = new StringBuilder();
                for (String storeName : storeNameList) {
                    sb.append(storeName).append(",");
                }
                // 可用店铺列表文本，逗号分隔，最后一个逗号截取掉
                String storesTxt = sb.toString().substring(0, sb.toString().length() - 1);
                activityDetail.setStoresTxt(storesTxt);
            }
        }
    

        // 券当天可发剩余 和 总的可发剩余
        QryPromExecDetailReq req = new QryPromExecDetailReq();
        req.setActivityId(activityId);
        try {
            QryPromExecDetailRsp rsp = promotionaMgmtService.queryPromotionExecDetail(req);
            if (null != rsp) {
                activityDetail.setLeftTotal(StringUtils.isNotBlank(rsp.getActRemainCount())
                        ? Integer.parseInt(rsp.getActRemainCount()) : 0);
                activityDetail.setTodayLeft(StringUtils.isNotBlank(rsp.getDayActRemainCount())
                        ? Integer.parseInt(rsp.getDayActRemainCount()) : 0);
            }
        } catch (RscException e) {
            LOGGER.error("查询券剩余量失败,activityId=" + activityId + ",error=" + e);
        }
        // 线下券查询剩余额度
        if (isOffLineCoupon(activity.getCouponResource())) {
            QueryPrechargeLimitRtn queryRtn = posPreChargeService.posQueryPrechargeLimit(activity.getStoreCode(),
                    activity.getBranchCode());
            if (queryRtn != null && PreChargeErrorConstants.QUREY_REMIAN_SUCCESS.equals(queryRtn.getErrFlag())) {
                activityDetail.setCouponLimit(queryRtn.getCouponLimit());
            }
        }
        activityDetail.setActivityId(AESUtils.encrypt(activityId, ConfigConstants.AES_KEY));
        activityDetail.setActivityName(activity.getActivityName());
        activityDetail.setStartTime(sdTime.format(activity.getStartTime()));
        activityDetail.setEndTime(sdTime.format(activity.getEndTime()));

        ret.setData(activityDetail);
        ret.setRetFlag(ReturnMsg.SUCCESS);
    
        return ret;
    
    }


    private ValidActivity queryActByActId(String staffId, String activityId) {
        Query query = new Query();
        Criteria criteria = new Criteria();
        criteria.and(ValidActivity.Attributes.OA_ACCOUNT_NO).is(staffId).and(ValidActivity.Attributes.ACTIVITY_ID)
                .is(activityId);
        query.addCriteria(criteria);
        return mongoTemplate.findOne(query, ValidActivity.class);
    }

    private boolean isOffLineCoupon(Integer couponResource) {
        return couponResource != null && (couponResource == PromotionConstants.PROMOT_COUPON_RESCOUCE_OFFLINE_STORE
                || couponResource == PromotionConstants.PROMOT_COUPON_RESCOUCE_OFFLINE_MARKET);
    }

    @Override
    public ReturnMsg<CommonRtn> sendCoupon(String activityIdEncrypt, String telNo, String oaAccountNo,
            String storeCode) {
        ReturnMsg<CommonRtn> ret = new ReturnMsg<CommonRtn>();
        // 校验入参
        if (StringUtils.isBlank(activityIdEncrypt) || StringUtils.isBlank(telNo) || StringUtils.isBlank(oaAccountNo)) {
            ret.setError(PromotionErrorConstants.COUPON_SEND_ERR_E001, PromotionErrorConstants.COUPON_SEND_ERR_MAP);
            return ret;
        }
        // 解密活动编码
        String activityId = AESUtils.decrypt(activityIdEncrypt, ConfigConstants.AES_KEY);
        // 调用会员接口查询会员编码
        LocateMemberInfo memberInfo = memberInfoService.locateMemberByMobileNo(telNo);
        if ((memberInfo == null) || (StringUtils.isBlank(memberInfo.getCustNum()))) {
            ret.setError(PromotionErrorConstants.COUPON_SEND_ERR_E002, PromotionErrorConstants.COUPON_SEND_ERR_MAP);
            return ret;
        }
        // 查询已校验的活动信息
        ValidActivity activity = queryActByActId(oaAccountNo, activityId);
        if (activity == null) {
            ret.setError(PromotionErrorConstants.COUPON_SEND_ERR_E003, PromotionErrorConstants.COUPON_SEND_ERR_MAP);
            return ret;
        }
        // 线下券判断发券工号所属门店与验证活动所属门店是否一致 如果此工号所属门店变化，之前门店验证的活动不能发券
        if (isOffLineCoupon(activity.getCouponResource()) && !storeCode.equals(activity.getStoreCode())) {
            ret.setError(PromotionErrorConstants.COUPON_SEND_ERR_E008, PromotionErrorConstants.COUPON_SEND_ERR_MAP);
            return ret;
        }
        String offLineOrderId = "";
        boolean offLineCoupon = false;
        // 线下券需要校验门店额度是否大于发券额度
        if (isOffLineCoupon(activity.getCouponResource())) {
            offLineCoupon = true;
            String branchCode = activity.getBranchCode();
            if (StringUtils.isBlank(branchCode)) {
                // 分公司编码补偿逻辑前置，因为有些门店信息MQ变更通知会比较滞后
                StoreInfo store = storeInfoService.queryStoreByCode(storeCode);
                branchCode = store != null ? store.getSaleBranchCode() : "";
                updateValidActivityBranchCode(branchCode, activityId, oaAccountNo);
                activity.setBranchCode(branchCode);
            }
            QueryCouponRtn queryCouponDetail = promotionCouponService.queryCouponDetail(activityId,
                    memberInfo.getCustNum(), activity.getActivitySecretKey(), activity.getCityId(), activity);
            if (queryCouponDetail == null) {
                ret.setError(PromotionErrorConstants.COUPON_SEND_ERR_E004, PromotionErrorConstants.COUPON_SEND_ERR_MAP);
                return ret;
            } else if (!PromotionErrorConstants.COUPON_SEND_STORE_INVALID.equals(queryCouponDetail.getFailReason())
                    && StringUtils.isBlank(queryCouponDetail.getCouponAmount())) {
                ret.setError(queryCouponDetail.getFailReason(), queryCouponDetail.getFailMsg());
                return ret;
            } else if (PromotionErrorConstants.COUPON_SEND_STORE_INVALID.equals(queryCouponDetail.getFailReason())) {
                deleteValidAct(activity.getActivityId(), activity.getOaAccountNo());
                ret.setError(PromotionErrorConstants.COUPON_SEND_ERR_E012, PromotionErrorConstants.COUPON_SEND_ERR_MAP);
                return ret;
            }
            QueryPrechargeLimitRtn queryRtn = posPreChargeService.posQueryPrechargeLimit(activity.getStoreCode(),
                    branchCode);
            if (queryRtn == null || StringUtils.isBlank(queryRtn.getCouponLimit())) {
                ret.setError(PromotionErrorConstants.COUPON_SEND_ERR_E010, PromotionErrorConstants.COUPON_SEND_ERR_MAP);
                return ret;
            }
            BigDecimal couponValue = new BigDecimal(queryCouponDetail.getCouponAmount());
            BigDecimal couponLimit = new BigDecimal(queryRtn.getCouponLimit());
            if (couponValue.compareTo(couponLimit) > 0) {
                ret.setError(PromotionErrorConstants.COUPON_SEND_ERR_E011, PromotionErrorConstants.COUPON_SEND_ERR_MAP);
                return ret;
            }
            // 生成下线券orderId
            StringBuilder sb = new StringBuilder(SEND_COUPON_ORDER_PREFIX);
            offLineOrderId = sb.append(sequenceSerivce.incrSequenceNumber(COUPON_ORDER_ID_KEY)).toString();
        }
        // 调用发券接口
        SendCouponRtn couponRtn = promotionCouponService.sendCoupon(activityId, activity.getCityId(),
                memberInfo.getCustNum(), activity.getActivitySecretKey(), PromotionConstants.SYS_CODE_SNSAWP, activity,
                offLineOrderId);
        // 判断发券返回结果
        if (couponRtn != null && PromotionConstants.SUCCESS.equals(couponRtn.getRetFlag())) {
            ret.setRetFlag(ReturnMsg.SUCCESS);
            if (StringUtils.isBlank(storeCode)) {
                storeCode = storeManRemoteService.getStoreCodeByStaffId(oaAccountNo);
            }
            // 插入发券记录表
            CouponRecord record = new CouponRecord();
            record.setActivityId(activityId);
            record.setActivityName(activity.getActivityName());
            record.setActEndTime(activity.getEndTime());
            record.setActStartTime(activity.getStartTime());
            record.setCouponId(couponRtn.getCouponId());
            record.setCouponNo(couponRtn.getCouponNo());
            record.setCouponType(couponRtn.getCouponType());
            record.setCouponAmount(couponRtn.getCouponAmount());
            record.setCustNo(memberInfo.getCustNum());
            record.setCouponName(couponRtn.getCouponName());
            record.setTelNo(telNo);
            record.setOaAccountNo(oaAccountNo);
            record.setOffLineOrderId(offLineOrderId);
            record.setSendTime(new Date());
            if (StringUtils.isNotBlank(storeCode)) {
                record.setStoreCode(storeCode);
                StoreInfo store = storeInfoService.queryStoreByCode(storeCode);
                if (store != null) {
                    record.setStoreName(store.getStoreName());
                    record.setRegionCode(store.getRegionCode());
                    record.setRegionName(store.getRegionName());
                }
            }
            mongoTemplate.save(record);
            // 调用用户信息采集接口，记录用户行为
            try {
                ConsumerBehaviorDto behavior = new ConsumerBehaviorDto();
                behavior.setBehaviorName(activity.getActivityName());
                behavior.setCustNo(memberInfo.getCustNum());
                behavior.setBehaviorTime(System.currentTimeMillis());
                behavior.setStaffId(oaAccountNo);
                behavior.setPhoneNo(telNo);
                behavior.setBehaviorType(ConsumerBehaviorType.COUPON);
                storeConsumerService.upsertConsumerBehavior(behavior);
            } catch (Exception e) {
                LOGGER.error(
                        "发促销券采集用户信息失败,工号:" + oaAccountNo + ",活动Id:" + activityId + ",会员编码:" + memberInfo.getCustNum(),
                        e);
            }
        } else if (couponRtn != null) {
            // 线下券返回错误编码为3 门店不符合 删除此常用活动
            if (offLineCoupon && PromotionErrorConstants.COUPON_SEND_STORE_INVALID.equals(couponRtn.getErrorCode())) {
                deleteValidAct(activity.getActivityId(), activity.getOaAccountNo());
                ret.setError(PromotionErrorConstants.COUPON_SEND_ERR_E012, PromotionErrorConstants.COUPON_SEND_ERR_MAP);
            } else {
                // 返回客户端 接口返回的错误编码和错误信息 服务端不做封装 产品确认
                ret.setError(couponRtn.getErrorCode(), couponRtn.getErrorMsg());
            }
        } else {
            // 发券接口返回对象为空，处理失败
            ret.setError(PromotionErrorConstants.COUPON_SEND_ERR_E004, PromotionErrorConstants.COUPON_SEND_ERR_MAP);
        }
        return ret;
    }

    private void updateValidActivityBranchCode(String branchCode, String actId, String oaAccountNo) {
        if (StringUtils.isNotBlank(branchCode)) {
            Query query = new Query();
            Criteria criteria = new Criteria();
            criteria.and(ValidActivity.Attributes.ACTIVITY_ID).is(actId).and(ValidActivity.Attributes.OA_ACCOUNT_NO)
                    .is(oaAccountNo);
            query.addCriteria(criteria);
            Update update = new Update();
            update.set(ValidActivity.Attributes.BRANCH_CODE, branchCode);
            mongoTemplate.updateFirst(query, update, ValidActivity.class);
        }
    }

    /**
     * 
     * 功能描述:删除常用活动 <br>
     * 〈功能详细描述〉
     * 
     * @param actId
     * @param staffId
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    private void deleteValidAct(String actId, String staffId) {
        Query query = new Query();
        Criteria criteria = new Criteria();
        criteria.and(ValidActivity.Attributes.OA_ACCOUNT_NO).is(staffId).and(ValidActivity.Attributes.ACTIVITY_ID)
                .is(actId);
        query.addCriteria(criteria);
        mongoTemplate.remove(query, ValidActivity.class);
    }

    /**
     * 将客户端传过来的活动信息保存进数据库
     * 
     * @param activityId
     * @param activityName
     * @param cityId
     * @param endTime
     * @param mobile
     * @param securityKey
     * @param startTime
     * @param staffId
     */
    private void addActivityDetail(String activityId, String activityName, String cityId, String endTime,
            String securityKey, String startTime, Integer couponResource, String storeCode, String staffId) {
        String branchCode = "";
        if (StringUtils.isNotBlank(storeCode)) {
            StoreInfo store = storeInfoService.queryStoreByCode(storeCode);
            branchCode = store != null ? store.getSaleBranchCode() : "";
        }
        Query query = new Query();
        Criteria criteria = new Criteria();
        criteria.and(ValidActivity.Attributes.OA_ACCOUNT_NO).is(staffId).and(ValidActivity.Attributes.ACTIVITY_ID)
                .is(activityId);
        query.addCriteria(criteria);
        Update update = new Update();
        update.set(ValidActivity.Attributes.STORE_CODE, storeCode);
        update.set(ValidActivity.Attributes.ACTIVITY_ID, activityId);
        update.set(ValidActivity.Attributes.ACTIVITY_NAME, activityName);
        update.set(ValidActivity.Attributes.ACTIVITY_SECRET_KEY, securityKey);
        update.set(ValidActivity.Attributes.BRANCH_CODE, branchCode);
        update.set(ValidActivity.Attributes.OA_ACCOUNT_NO, staffId);
        update.set(ValidActivity.Attributes.COUPON_RESOURCE, couponResource);
        update.set(ValidActivity.Attributes.START_TIME,
                DateUtils.getDateByStr(startTime, DateUtils.DEFAULT_TIME_PATTERN));
        update.set(ValidActivity.Attributes.END_TIME, DateUtils.getDateByStr(endTime, DateUtils.DEFAULT_TIME_PATTERN));
        update.set(ValidActivity.Attributes.CITY_ID, StringUtils.isNotBlank(cityId) ? cityId : "");
        mongoTemplate.upsert(query, update, ValidActivity.class);
    }

    @Override
    public Integer queryExportCount(String startTime, String endTime) {
        SimpleDateFormat sdFormat = new SimpleDateFormat("yyyy-MM-dd");
        try {
            Date startDate = sdFormat.parse(startTime);
            Date endDate = sdFormat.parse(endTime);
            Criteria criteria = new Criteria();
            criteria.and(CouponRecord.Attributes.SEND_TIME).gt(startDate).lt(endDate);
            Query query = new Query();
            query.addCriteria(criteria);
            Long count = mongoTemplate.count(query, CouponRecord.class);
            return count.intValue();
        } catch (ParseException e) {
            LOGGER.error("查询导出发券记录数量，时间转换异常,startTime=" + startTime + ",endTime=" + endTime, e);
        }
        return null;
    }

    @Override
    public File exportRecordExcel(String startTime, String endTime) {
        Integer count = queryExportCount(startTime, endTime);
        String maxCount = ConfigUtil.getConfig(ConfigConstants.SAWP_CONFIG_PATH, ConfigConstants.MAX_EXPORT_COUNT,
                ConfigConstants.DEFAULT_MAX_EXPORT_COUNT);
        if (count == null || count > Integer.parseInt(maxCount)) {
            return null;
        }
        String pageLimit = ConfigUtil.getConfig(ConfigConstants.SAWP_CONFIG_PATH, ConfigConstants.EXPORT_COUNT_PAGE,
                ConfigConstants.DEFAULT_EXPORT_COUNT_PAGE);
        Integer pageSize = Integer.valueOf(pageLimit);
        int pages = (count - 1) / pageSize + 1;
        SXSSFWorkbook wb = new SXSSFWorkbook(pageSize);
        Sheet sh = wb.createSheet();
        int rowNum = 0;
        SimpleDateFormat sdFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        for (int i = 0; i < pages; i++) {
            List<CouponRecord> list = queryRecordExport(startTime, endTime, i * pageSize, pageSize);
            if (CollectionUtils.isEmpty(list)) {
                continue;
            }
            if (rowNum == 0) {
                Row row = sh.createRow(rowNum++);
                // 定义表头
                String[] title = "日期,券名称,工号,门店编码,门店名称,发券大区".split(",");
                for (int k = 0; k < title.length; k++) {
                    Cell cell = row.createCell(k);
                    cell.setCellValue(title[k]);
                }
            }
            try {
                for (CouponRecord record : list) {
                    Row row = sh.createRow(rowNum++);
                    row.createCell(0)
                            .setCellValue(record.getSendTime() == null ? "" : sdFormat.format(record.getSendTime()));
                    row.createCell(1).setCellValue(record.getCouponName() == null ? "" : record.getCouponName());
                    row.createCell(2).setCellValue(record.getOaAccountNo() == null ? "" : record.getOaAccountNo());
                    row.createCell(3).setCellValue(record.getStoreCode() == null ? "" : record.getStoreCode());
                    row.createCell(4).setCellValue(record.getStoreName() == null ? "" : record.getStoreName());
                    row.createCell(5).setCellValue(record.getRegionName() == null ? "" : record.getRegionName());
                }
            } catch (Exception e) {
                LOGGER.error("生产execl失败" + e);
            }
        }
        FileOutputStream out = null;
        try {
            final File createTempFile = File.createTempFile("temp1", "temp1.xlsx");
            out = new FileOutputStream(createTempFile);
            wb.write(out);
            return createTempFile;
        } catch (Exception e) {
            LOGGER.error("生成导出文件失败.", e);
        } finally {
            if (null != out) {
                try {
                    out.close();
                } catch (IOException e) {
                    LOGGER.error("生成导出文件失败.", e);
                }
            }
            wb.dispose();
        }
        return null;
    }

    private List<CouponRecord> queryRecordExport(String startTime, String endTime, Integer start, Integer limit) {
        SimpleDateFormat sdFormat = new SimpleDateFormat("yyyy-MM-dd");
        List<CouponRecord> list = new ArrayList<CouponRecord>();
        try {
            Date startDate = sdFormat.parse(startTime);
            Date endDate = sdFormat.parse(endTime);
            Criteria criteria = new Criteria();
            criteria.and(CouponRecord.Attributes.SEND_TIME).gt(startDate).lt(endDate);
            Query query = new Query();
            query.addCriteria(criteria);
            query.skip(start);
            query.limit(limit);
            // 排序参数 按照发送时间倒序
            query.with(new Sort(new Order(Direction.DESC, CouponRecord.Attributes.SEND_TIME)));
            list = mongoTemplate.find(query, CouponRecord.class);
        } catch (ParseException e) {
            LOGGER.error("查询导出发券记录数量，时间转换异常,startTime=" + startTime + ",endTime=" + endTime, e);
        }
        return list;
    }

    @Override
    public ReturnMsg<QueryResult<CouponSendRecordBean>> queryCouponSendRecord(String startTimeStr, String endTimeStr,
            String regionCode, String storeCode, String activityName, int startIndex, int pageSize) {
        ReturnMsg<QueryResult<CouponSendRecordBean>> rtn = new ReturnMsg<QueryResult<CouponSendRecordBean>>();
        QueryResult<CouponSendRecordBean> queryRtn = new QueryResult<CouponSendRecordBean>();
        // 获取最大分页查询数量 如果超过最大默认值，取默认值
        int queryLimit = Integer.parseInt(ConfigUtil.getConfig(ConfigConstants.SAWP_CONFIG_PATH,
                ConfigConstants.COUPON_RECORD_QUERY_LIMIT, ConfigConstants.DEFAULT_QUERY_COUPON_LIMIT));
        queryLimit = pageSize > queryLimit ? queryLimit : pageSize;

        Date startTime = DateUtils.getDateByStr(startTimeStr, DateUtils.DEFAULT_DAY_PATTERN);
        Date endTime = DateUtils.getDateByStr(endTimeStr, DateUtils.DEFAULT_DAY_PATTERN);

        List<CouponSendRecordBean> couponList = promotionActivityDaoService.queryCouponRecordForPage(startTime, endTime,
                regionCode, storeCode, activityName, startIndex, queryLimit);

        int totalSize = couponList.size();
        queryRtn.setTotalSize(totalSize);
        List<CouponSendRecordBean> retList = new ArrayList<CouponSendRecordBean>();
        int endIndex = startIndex + queryLimit;
        if (endIndex > totalSize) {
            endIndex = totalSize;
        }
        for (int i = startIndex; i < endIndex; i++) {
            retList.add(couponList.get(i));
        }
        queryRtn.setRecords(retList);
        rtn.setData(queryRtn);

        return rtn;
    }

    @Override
    public ReturnMsg<CommonRtn> validActivity(String activityId, String activityIdSec, String activityName,
            String cityId, String endTime, String startTime, String securityKey, Integer couponResource,
            String storeCode, String userId) {
        ReturnMsg<CommonRtn> ret = new ReturnMsg<CommonRtn>();
        Integer failedTimes = getFailedTimes(userId);
        Integer failLimit = Integer.valueOf(ConfigUtil.getConfig(ConfigConstants.SAWP_CONFIG_PATH,
                ConfigConstants.FAIL_VALID_TIMES, ConfigConstants.DEFAULT_FAIL_VALID_TIMES));
        if (failedTimes > failLimit) {
            ret.setRetFlag(ReturnMsg.FAIL);
            ret.setErrorCode(PromotionErrorConstants.VALID_ACT_ERR_E003);
            ret.setErrorMessage(
                    PromotionErrorConstants.VALID_ACT_ERR_MAP.get(PromotionErrorConstants.VALID_ACT_ERR_E003));
            return ret;
        }
        if (!activityId.equals(AESUtils.decrypt(activityIdSec, ConfigConstants.AES_KEY))) {
            cacheUtils.hset(CacheKeyConstants.VALID_ACT_FAIL_TIMES, sd.format(new Date()) + userId, failedTimes + 1);
            ret.setError(PromotionErrorConstants.VALID_ACT_ERR_E002, PromotionErrorConstants.VALID_ACT_ERR_MAP);
            return ret;
        }
        if (isOffLineCoupon(couponResource) && StringUtils.isBlank(storeCode)) {
            ret.setError(PromotionErrorConstants.VALID_ACT_ERR_E004, PromotionErrorConstants.VALID_ACT_ERR_MAP);
            return ret;
        }
        // 校验成功保存常用活动
        addActivityDetail(activityId, activityName, cityId, endTime, securityKey, startTime, couponResource, storeCode,
                userId);
        ret.setRetFlag(ReturnMsg.SUCCESS);
        return ret;
    }

    @Override
    public ReturnMsg<CommonRtn> validActivityIdNew(ValidActivityIdReq validActivityIdReq, String userId) {
        ReturnMsg<CommonRtn> ret = new ReturnMsg<CommonRtn>();
        Integer failedTimes = getFailedTimes(userId);
        Integer failLimit = Integer.valueOf(ConfigUtil.getConfig(ConfigConstants.SAWP_CONFIG_PATH,
                ConfigConstants.FAIL_VALID_TIMES, ConfigConstants.DEFAULT_FAIL_VALID_TIMES));
        if (failedTimes > failLimit) {
            ret.setRetFlag(ReturnMsg.FAIL);
            ret.setErrorCode(PromotionErrorConstants.VALID_ACT_ERR_E003);
            ret.setErrorMessage(
                    PromotionErrorConstants.VALID_ACT_ERR_MAP.get(PromotionErrorConstants.VALID_ACT_ERR_E003));
            return ret;
        }
        if (!validActivityIdReq.getActivityId().equals(AESUtils.decrypt(validActivityIdReq.getActivityIdSec(), ConfigConstants.AES_KEY))) {
            cacheUtils.hset(CacheKeyConstants.VALID_ACT_FAIL_TIMES, sd.format(new Date()) + userId, failedTimes + 1);
            ret.setError(PromotionErrorConstants.VALID_ACT_ERR_E002, PromotionErrorConstants.VALID_ACT_ERR_MAP);
            return ret;
        }
        if (isOffLineCoupon(validActivityIdReq.getCouponResource()) && StringUtils.isBlank(validActivityIdReq.getStoreCode())) {
            ret.setError(PromotionErrorConstants.VALID_ACT_ERR_E004, PromotionErrorConstants.VALID_ACT_ERR_MAP);
            return ret;
        }
        // 校验成功保存常用活动
        addActivityNewDetail(validActivityIdReq, userId);
        ret.setRetFlag(ReturnMsg.SUCCESS);
        return ret;
    
    }
    
    private void addActivityNewDetail(ValidActivityIdReq validActivityIdReq, String userId) {
        String branchCode = "";
        if (StringUtils.isNotBlank(validActivityIdReq.getStoreCode())) {
            StoreInfo store = storeInfoService.queryStoreByCode(validActivityIdReq.getStoreCode());
            branchCode = store != null ? store.getSaleBranchCode() : "";
        }
        Query query = new Query();
        Criteria criteria = new Criteria();
        criteria.and(ValidActivity.Attributes.OA_ACCOUNT_NO).is(userId).and(ValidActivity.Attributes.ACTIVITY_ID)
                .is(validActivityIdReq.getActivityId());
        query.addCriteria(criteria);
        Update update = new Update();
        update.set(ValidActivity.Attributes.STORE_CODE,validActivityIdReq.getStoreCode());
        update.set(ValidActivity.Attributes.ACTIVITY_ID, validActivityIdReq.getActivityId());
        update.set(ValidActivity.Attributes.ACTIVITY_NAME, validActivityIdReq.getActivityName());
        update.set(ValidActivity.Attributes.ACTIVITY_SECRET_KEY, validActivityIdReq.getSecurityKey());
        update.set(ValidActivity.Attributes.BRANCH_CODE,branchCode);
        update.set(ValidActivity.Attributes.OA_ACCOUNT_NO, userId);
        update.set(ValidActivity.Attributes.COUPON_RESOURCE,validActivityIdReq.getCouponResource());
        update.set(ValidActivity.Attributes.START_TIME,
                DateUtils.getDateByStr(validActivityIdReq.getStartTime(), DateUtils.DEFAULT_TIME_PATTERN));
        update.set(ValidActivity.Attributes.END_TIME, DateUtils.getDateByStr(validActivityIdReq.getEndTime(), DateUtils.DEFAULT_TIME_PATTERN));
        update.set(ValidActivity.Attributes.CITY_ID, StringUtils.isNotBlank(validActivityIdReq.getCityId()) ? validActivityIdReq.getCityId() : "");
        update.set(ValidActivity.Attributes.COUPON_RULE_CODE, validActivityIdReq.getCouponRuleCode());
        update.set(ValidActivity.Attributes.COUPON_TYPE, validActivityIdReq.getCouponType());
        update.set(ValidActivity.Attributes.COUPON_VALUE, validActivityIdReq.getCouponValue());
        mongoTemplate.upsert(query, update, ValidActivity.class);
    }

    /**
     * 
     * 功能描述: 获取当天已校验失败的次数<br>
     * 〈功能详细描述〉
     * 
     * @param userId
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    private Integer getFailedTimes(String userId) {
        Integer validTimes = cacheUtils.hget(CacheKeyConstants.VALID_ACT_FAIL_TIMES, sd.format(new Date()) + userId,
                Integer.class);
        return validTimes == null ? Integer.valueOf("0") : validTimes;
    }

    @Override
    public String synCouponRecord() {
        Query query = new Query();
        Criteria criteria = new Criteria();
        criteria.and("storeCode").exists(false);
        query.addCriteria(criteria);
        long count = mongoTemplate.count(query, CouponRecord.class);
        int success = 0;
        int fail = 0;
        StringBuilder sb = new StringBuilder();
        StringBuilder sb1 = new StringBuilder();
        StringBuilder sb2 = new StringBuilder();
        if (count > 0) {
            int pageSize = 500;
            int pageNo = (int) (count / pageSize) + 1;
            for (int i = 0; i < pageNo; i++) {
                query.skip(pageSize * i).limit(pageSize);
                List<CouponRecord> couponList = mongoTemplate.find(query, CouponRecord.class);
                if (CollectionUtils.isNotEmpty(couponList)) {
                    for (CouponRecord coupon : couponList) {
                        if (StringUtils.isNotBlank(coupon.getOaAccountNo())) {
                            String storeCode = storeManRemoteService.getStoreCodeByStaffId(coupon.getOaAccountNo());
                            if (StringUtils.isNotBlank(storeCode)) {
                                StoreInfo store = storeInfoService.queryStoreByCode(storeCode);
                                if (store != null) {
                                    Query query1 = new Query();
                                    Criteria criteria1 = new Criteria();
                                    criteria1.and("_id").is(coupon.getId());
                                    query1.addCriteria(criteria1);
                                    Update update = new Update();
                                    update.set("regionCode", store.getRegionCode());
                                    update.set("regionName", store.getRegionName());
                                    update.set("storeName", store.getStoreName());
                                    update.set("storeCode", storeCode);
                                    try {
                                        mongoTemplate.updateFirst(query1, update, CouponRecord.class);
                                        success = success + 1;
                                    } catch (Exception e) {
                                        fail = fail + 1;
                                        sb.append("_id=").append(coupon.getId());
                                        LOGGER.error("同步发券记录异常,id=" + coupon.getId(), e);
                                    }
                                } else {
                                    sb2.append("--storeCode=").append(storeCode);
                                }
                            } else {
                                sb1.append("--oaNo=").append(coupon.getOaAccountNo());
                            }
                        }
                    }
                }
            }
        }
        return "总条数:" + count + "成功条数:" + success + "失败条数:" + fail + "失败Ids:" + sb.toString() + "没有门店工号:"
                + sb1.toString() + "未找到门店信息，门店编码:" + sb2.toString();
    }

    @Override
    public Workbook exportSendCouponStat(String activityName, String startTimeStr, String endTimeStr, String regionCode,
            String storeCode) {
        Workbook workbook = null;
        try {
            Date startTime = DateUtils.getDateByStr(startTimeStr, DateUtils.DEFAULT_DAY_PATTERN);
            Date endTime = DateUtils.getDateByStr(endTimeStr, DateUtils.DEFAULT_DAY_PATTERN);
            String maxCount = ConfigUtil.getConfig(ConfigConstants.SAWP_CONFIG_PATH, ConfigConstants.MAX_EXPORT_COUNT,
                    ConfigConstants.DEFAULT_MAX_EXPORT_COUNT);
            List<CouponSendRecordBean> couponList = promotionActivityDaoService.queryCouponRecordForPage(startTime,
                    endTime, regionCode, storeCode, activityName, null, null);
            if (couponList.size() <= Integer.parseInt(maxCount)) {
                // 生成EXCEL
                // 带生成的标题栏
                String[] titles = { "活动名称", "大区名称", "门店名称", "发券数量" };
                // 准备待导出的数据
                List<String[]> datas = new ArrayList<String[]>();
                for (CouponSendRecordBean coupon : couponList) {
                    String[] data = new String[4];
                    data[0] = coupon.getActivityName();
                    data[1] = coupon.getRegionName();
                    data[2] = coupon.getStoreName();
                    data[3] = String.valueOf(coupon.getCouponCount());
                    datas.add(data);
                }
                // 导出EXCEL
                workbook = ExcelUtils.createExcel(datas, titles);
            }
        } catch (Exception e) {
            LOGGER.error("异业券统计导出异常", e);
        }
        return workbook;
    }

    @Override
    public ReturnMsg<String> checkSendCouponStatExport(String activityName, String startTimeStr, String endTimeStr,
            String regionCode, String storeCode) {
        ReturnMsg<String> returnMsg = new ReturnMsg<String>();
        if (StringUtils.isBlank(startTimeStr) || StringUtils.isBlank(endTimeStr) || StringUtils.isBlank(regionCode)) {
            returnMsg.setError(ErrorCodeConstants.ERR_0001);
            return returnMsg;
        }
        Date startTime = DateUtils.getDateByStr(startTimeStr, DateUtils.DEFAULT_DAY_PATTERN);
        Date endTime = DateUtils.getDateByStr(endTimeStr, DateUtils.DEFAULT_DAY_PATTERN);
        List<CouponSendRecordBean> couponList = promotionActivityDaoService.queryCouponRecordForPage(startTime, endTime,
                regionCode, storeCode, activityName, null, null);
        String maxCount = ConfigUtil.getConfig(ConfigConstants.SAWP_CONFIG_PATH, ConfigConstants.MAX_EXPORT_COUNT,
                ConfigConstants.DEFAULT_MAX_EXPORT_COUNT);
        int exportSize = couponList == null ? 0 : couponList.size();
        if (exportSize > Integer.parseInt(maxCount)) {
            returnMsg.setError(ErrorCodeConstants.ERR_0006, maxCount);
        } else if (exportSize == 0) {
            returnMsg.setError(ErrorCodeConstants.ERR_0019);
        } else {
            returnMsg.setData(String.valueOf(couponList.size()));
        }
        return returnMsg;
    }


    @Override
    public ReturnMsg<List<CouponCommInfo>> queryCouponByCommList(CouponReq couponReq, String userId) {
        LOGGER.info("queryCouponByCommList  beg, couponReq :{},userId:{}" ,couponReq , userId);
        ReturnMsg<List<CouponCommInfo>> ret = new ReturnMsg<List<CouponCommInfo>>();
        QryCouponListRsp rsp = promotionCouponService.queryCouponByCommList(couponReq);

        if(rsp == null || PromotionConstants.FAILED.equals(rsp.getResult()) ){
            ret.setRetFlag(ReturnMsg.FAIL);
            ret.setErrorCode(ErrorCodeConstants.ERR_0002);
            ret.setErrorCode(ErrorCodeConstants.ERR_MAP.get(ErrorCodeConstants.ERR_0002));
            return ret;
        }
        Map<String,CouponCommInfo> coupomMap = new HashMap<String,CouponCommInfo>();
        List<CouponDetail>  couponList = rsp.getActInfoList();
        for(CouponDetail item : couponList){
            if(item!=null &&CollectionUtils.isNotEmpty(item.getProductList())){
                for(ProductDetail itemIn : item.getProductList()){
                    if(itemIn ==null || StringUtils.isBlank(itemIn.getProductId()) ){
                        continue;
                    }
                    if(!coupomMap.containsKey(itemIn.getProductId())){
                        CouponCommInfo info = new CouponCommInfo();
                        info.setCommCode(itemIn.getProductId());
                        info.setCouponNum(1);
                        info.setCouponRule(item.getCouponPromotionLabel());
                        double cValue = Double.valueOf(item.getCouponValue());
                        info.setCouponValue( cValue);
                        coupomMap.put(itemIn.getProductId(), info);
                    }else {
                        double cValue = Double.valueOf(item.getCouponValue());
                        CouponCommInfo comInfo =  coupomMap.get(itemIn.getProductId());
                        if(cValue> comInfo.getCouponValue() ){
                            comInfo.setCouponValue(cValue);
                            comInfo.setCouponRule(item.getCouponPromotionLabel());
                        }
                        comInfo.setCouponNum(comInfo.getCouponNum() + 1);
                    }
                }
            }
        }
        List<CouponCommInfo> couponCommInfoList = new ArrayList<CouponCommInfo>(coupomMap.values());
        ret.setData(couponCommInfoList);
        LOGGER.info("queryCouponByCommList couponCommInfoList :" + couponCommInfoList);
        return ret;
    }


    @Override
    public ReturnMsg<List<InnerCouponDetail>> queryCouponInfoByComm(String actType, String cityId, String commCode,
            String storeId,String staffId) {
        LOGGER.info("queryCouponInfoByComm , 开始查询, commCode=" + commCode  + ",actType="
                + actType + ",cityId=" + cityId + ",storeId=" + storeId );
        ReturnMsg<List<InnerCouponDetail>> ret = new ReturnMsg<List<InnerCouponDetail>>();
        CouponReq couponReq = new CouponReq();
        couponReq.setCityId(cityId);
        List<CommInfoReq> comReqList = new ArrayList<CommInfoReq>();
        CommInfoReq  commInfoReq = new CommInfoReq();
        commInfoReq.setActType(actType);
        commInfoReq.setCommCode(commCode);
        commInfoReq.setStoreId(storeId);
        comReqList.add(commInfoReq);
        couponReq.setCommInfoList(comReqList);
        QryCouponListRsp rsp = promotionCouponService.queryCouponByCommList(couponReq);
        if(rsp == null || PromotionConstants.FAILED.equals(rsp.getResult()) ){
            LOGGER.error("queryCouponInfoByComm , queryCouponByCommList faill,couponReq:{},QryCouponListRsp:{}",couponReq,rsp);
            ret.setRetFlag(ReturnMsg.FAIL);
            ret.setErrorCode(ErrorCodeConstants.ERR_0002);
            ret.setErrorCode(ErrorCodeConstants.ERR_MAP.get(ErrorCodeConstants.ERR_0002));
            return ret;
        }
        
        
        if(CollectionUtils.isEmpty(rsp.getActInfoList())){
            LOGGER.info("queryCouponInfoByComm , queryCouponList blank");
            return ret;
        }
        ReturnMsg<List<InnerCouponDetail>>  innerCoupon = innerCouponService.queryCouponList(staffId);
        
        if(innerCoupon == null ||innerCoupon.getData() == null || ReturnMsg.FAIL.equals(innerCoupon.getRetFlag())){
            LOGGER.error("queryCouponInfoByComm , queryCouponList faill,staffId:{},innerCouponList:{}",staffId,innerCoupon);
            ret.setRetFlag(ReturnMsg.FAIL);
            ret.setErrorCode(ErrorCodeConstants.ERR_0002);
            ret.setErrorCode(ErrorCodeConstants.ERR_MAP.get(ErrorCodeConstants.ERR_0002));
            return ret;
        }
        List<InnerCouponDetail> innerCouponList =  innerCoupon.getData();
        
        if(CollectionUtils.isEmpty(innerCouponList)){
            LOGGER.error("queryCouponInfoByComm , queryCouponList faill,staffId:{},innerCouponList:{}",staffId,innerCoupon);
            return ret;
        }
        Map<String,InnerCouponDetail> mappedCoupon = Maps.uniqueIndex(innerCouponList, new Function <InnerCouponDetail,String> () {
            public String apply(InnerCouponDetail from) {
              return from.getActivityId(); 
            }});
        
        List<InnerCouponDetail> resultList = new ArrayList<InnerCouponDetail>();
       for(CouponDetail  item : rsp.getActInfoList()){
           if(item != null ){
               String activityIdSec = AESUtils.encrypt(item.getActivityId(), ConfigConstants.AES_KEY);
               if(mappedCoupon.containsKey(activityIdSec)){
                   InnerCouponDetail detail = mappedCoupon.get(activityIdSec);
                   detail.setCouponRuleId(item.getCouponRuleId());
                   resultList.add(detail);
               }
           }
       }
       ret.setData(resultList);
        return ret;
    }
    
}
